package cn.seamus.marksman.processor.impl;

import java.net.URL;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.methods.CloseableHttpResponse;

import cn.seamus.marksman.common.MarksmanException;
import cn.seamus.marksman.common.PageNavigator;
import cn.seamus.marksman.http.IHttpExecuter;
import cn.seamus.marksman.processor.Processor;

public abstract class AbstractProcessor implements Processor {
    private static Log logger = LogFactory.getLog(AbstractProcessor.class);

    private Map<String, IHttpExecuter> httpExecuterMap;

    private Map<PageNavigator, Processor> nextMap;

    private String proxyType;

    @Override
    public ProcessResult process(Map<String, Object> reqMap) throws MarksmanException {

        ProcessResult result = read(reqMap);

        if (result.getNavigator() == null || nextMap == null) {
            logger.info("processing done.");
            return result;
        }

        Processor nextProcessor = nextMap.get(result.getNavigator());
        if (nextProcessor == null) {
            logger.error("Error system configuration：Processor not configured. key=" + result.getNavigator());
            throw new RuntimeException("Error system configuration：Processor not configured. " + result.getNavigator());
        }

        return nextProcessor.process(prepareNext(result.getParams()));
    }

    protected abstract Map<String, Object> prepareNext(Map<String, Object> params) throws MarksmanException;

    protected abstract ProcessResult read(Map<String, Object> requestParams) throws MarksmanException;

    protected CloseableHttpResponse executeGet(URL url, Map<String, Object> params) throws MarksmanException {
        return getHttpExecuterMap().get(proxyType).executeGet(url, params);
    }

    protected CloseableHttpResponse executePost(URL url, Map<String, Object> params) throws MarksmanException {
        return getHttpExecuterMap().get(proxyType).executePost(url, params);
    }

    protected CloseableHttpResponse executePostAsync(URL url, Map<String, Object> params) throws MarksmanException {
       
        
        IHttpExecuter executer = getHttpExecuterMap().get(proxyType + "0");

        
//        Callable<CloseableHttpResponse> task = new HttpCallable(executer, url, params);
//        final ExecutorService pool = Executors.newFixedThreadPool(1);
//        Future<CloseableHttpResponse> future = pool.submit(task);
//
//        try {
//            CloseableHttpResponse result = future.get();
//            return result;
//        } catch (InterruptedException e) {
//            logger.error(e);
//            throw new MarksmanException(e);
//        } catch (ExecutionException e) {
//            logger.error(e);
//            throw new MarksmanException(e);
//        }

         return executer.executePost(url, params);
    }

    /**
     * @return the httpExecuterMap
     */
    public Map<String, IHttpExecuter> getHttpExecuterMap() {
        return httpExecuterMap;
    }

    /**
     * @param httpExecuterMap
     *            the httpExecuterMap to set
     */
    public void setHttpExecuterMap(Map<String, IHttpExecuter> httpExecuterMap) {
        this.httpExecuterMap = httpExecuterMap;
    }

    /**
     * @return the proxyType
     */
    public String getProxyType() {
        return proxyType;
    }

    /**
     * @param proxyType
     *            the proxyType to set
     */
    public void setProxyType(String proxyType) {
        this.proxyType = proxyType;
    }

    public Map<PageNavigator, Processor> getNextMap() {
        return nextMap;
    }

    public void setNextMap(Map<PageNavigator, Processor> nextMap) {
        this.nextMap = nextMap;
    }

}
